基于数组的堆排序算法的C语言实现

实现如下:

int getParent(int c);
int getLeft(int p);
int getRight(int p);
void swap(int *p1, int *p2);

void heap_sort(int *source, int length);
void max_heapify(int *source, int length, int loc);
void build_max_heap(int *source, int length);

void heap_sort_iteration(int *source, int length);
void max_heapify_iteration(int *source, int length, int loc);
void build_max_heap_iteration(int *source, int length);

int getParent(int c) {
    return (c - 1) / 2;
}
int getLeft(int p) {
    return p * 2 + 1;
}
int getRight(int p) {
    return p * 2 + 2;
}
void swap(int *p1, int *p2) {
    int temp = *p1;
    *p1 = *p2;
    *p2 = temp;
}


void max_heapify(int *source, int length, int loc) {
    int l = getLeft(loc);
    int r = getRight(loc);
    int max = loc;
    if (l < length && source[l] > source[max])
        max = l;
    if (r < length && source[r] > source[max])
        max = r;
    if (max == loc)
        return;
    swap(source + max, source + loc);
    max_heapify(source, length, max);
}
void build_max_heap(int *source, int length) {
    for (int i = getParent(length - 1); i >= 0; --i) {
        max_heapify(source, length, i);
    }
}
void heap_sort(int *source, int length) {
    build_max_heap(source, length);
    for (int i = length - 1; i > 0; --i) {
        swap(source, source + i);
        max_heapify(source, i, 0);
    }
}


void max_heapify_iteration(int *source, int length, int loc) {
    int l, r;
    int max = loc;
    while (loc < length) {
        l = getLeft(loc);
        r = getRight(loc);
        if (l < length && source[l] > source[max])
            max = l;
        if (r < length && source[r] > source[max])
            max = r;
        if (max == loc)
            return;
        swap(source + max, source + loc);
        loc = max;
    }
}
void build_max_heap_iteration(int *source, int length) {
    for (int i = getParent(length - 1); i >= 0; --i) {
        max_heapify_iteration(source, length, i);
    }
}
void heap_sort_iteration(int *source, int length) {
    build_max_heap(source, length);
    for (int i = length - 1; i > 0; --i) {
        swap(source, source + i);
        max_heapify_iteration(source, i, 0);
    }
}

堆排序是不稳定原地的排序。
该程序中使用的数组作为表示堆的数据结构,其计算左子女,右子女以及父节点的坐标的方式如parent,left_child,right_child所示。
max_heapify使其保持最大堆的性质,假设p节点左右两颗子树都是最大堆,max_heapify使p节点保持最大堆的性质,选取p节点的左右子女中最大的与p节点交换,然后递归的对交换后的节点继续进行max_heapify操作,直到到达叶子结点。max_heapify操作运行时间的渐近上界为 Ο(h) h为待操作节点的高度。
build_max_heap将一个数组建立为最大堆,从最后一个非叶子节点到根节点依次分别调用max_heapify函数即可。其操作时间的渐近确界为 Ο(n)
heap_sort函数对n个数进行堆排序,每次将最大堆的第一个元素和最后一个元素交换,得到最大的元素,将堆的元素个数减一后再对堆的根节点进行max_heapify操作,得到当前堆中最大元素,循环n-1次即可排序数组。其操作时间的渐近确界为 Ο(nlogn)
其上所有算法复杂度计算方法见算法导论第六章,涉及主定理不再赘述。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
以下是两堆数组的堆排序的C语言实现: 1. 堆排序算法思想步骤程序: ```c #include <stdio.h> // 交换两个元素的值 void swap(int* a, int* b) { int temp = *a; *a = *b; *b = temp; } // 调整堆 void heapify(int arr[], int n, int i) { int largest = i; // 初始化最大元素为根节点 int left = 2 * i + 1; // 左子节点 int right = 2 * i + 2; // 右子节点 // 如果左子节点大于根节点 if (left < n && arr[left] > arr[largest]) largest = left; // 如果右子节点大于当前最大节点 if (right < n && arr[right] > arr[largest]) largest = right; // 如果最大节点不是根节点 if (largest != i) { swap(&arr[i], &arr[largest]); // 递归调整堆 heapify(arr, n, largest); } } // 堆排序 void heapSort(int arr[], int n) { // 构建堆(从最后一个非叶子节点开始) for (int i = n / 2 - 1; i >= 0; i--) heapify(arr, n, i); // 逐个从堆中取出元素 for (int i = n - 1; i >= 0; i--) { swap(&arr[0], &arr[i]); // 将当前最大元素移到末尾 heapify(arr, i, 0); // 重新调整堆 } } int main() { int arr1[] = {4, 10, 3, 5, 1}; int arr2[] = {7, 2, 9, 6, 8}; int n1 = sizeof(arr1) / sizeof(arr1[0]); int n2 = sizeof(arr2) / sizeof(arr2[0]); heapSort(arr1, n1); heapSort(arr2, n2); printf("Sorted array1: "); for (int i = 0; i < n1; i++) printf("%d ", arr1[i]); printf("\n"); printf("Sorted array2: "); for (int i = 0; i < n2; i++) printf("%d ", arr2[i]); printf("\n"); return 0; } ``` 2. 选择排序算法思想步骤程序: ```c #include <stdio.h> // 交换两个元素的值 void swap(int* a, int* b) { int temp = *a; *a = *b; *b = temp; } // 选择排序 void selectionSort(int arr[], int n) { for (int i = 0; i < n - 1; i++) { int minIndex = i; // 在未排序部分中找到最小元素的索引 for (int j = i + 1; j < n; j++) { if (arr[j] < arr[minIndex]) minIndex = j; } // 将最小元素交换到已排序部分的末尾 swap(&arr[minIndex], &arr[i]); } } int main() { int arr1[] = {4, 10, 3, 5, 1}; int arr2[] = {7, 2, 9, 6, 8}; int n1 = sizeof(arr1) / sizeof(arr1[0]); int n2 = sizeof(arr2) / sizeof(arr2[0]); selectionSort(arr1, n1); selectionSort(arr2, n2); printf("Sorted array1: "); for (int i = 0; i < n1; i++) printf("%d ", arr1[i]); printf("\n"); printf("Sorted array2: "); for (int i = 0; i < n2; i++) printf("%d ", arr2[i]); printf("\n"); return 0; } ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值